package com.banmao.youZone.api;

import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpResponse;
import com.banmao.youZone.aop.delayedResponse.annotation.DelayedResponse;
import com.banmao.youZone.config.web.annotation.RequestSingleParam;
import com.banmao.youZone.consts.CommonConst;
import com.banmao.youZone.entity.*;
import com.banmao.youZone.entity.vo.JobConfig;
import com.banmao.youZone.mapper.HistoryMapper;
import com.banmao.youZone.mapper.RequestPropertyMapper;
import com.banmao.youZone.mapper.TaskTriggerMapper;
import com.banmao.youZone.mapper.UserMapper;
import com.banmao.youZone.util.ClockInUtil;
import com.banmao.youZone.util.RequestUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.annotation.Resource;
import jakarta.servlet.http.Cookie;
import lombok.extern.slf4j.Slf4j;
import org.quartz.SchedulerException;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

@Slf4j
@RestController
@RequestMapping("/api")
public class ApiController {

    @Resource
    private UserMapper userMapper;

    @Resource
    private RequestPropertyMapper requestPropertyMapper;

    @Resource
    private TaskTriggerMapper taskTriggerMapper;

    @Resource
    private ApiService apiService;

    @Resource
    private HistoryMapper historyMapper;

    @PostMapping("/selectUser/{userId}")
    public ResultData<String> selectUser(@PathVariable("userId") Integer userId) {
        Assert.notNull(userId, "userId 为空");

        UserVO userVO = userMapper.selectById(userId);
        if (userVO == null) {
            throw new IllegalArgumentException("未找到用户");
        }

        RequestUtil.getSession().setAttribute(CommonConst.USER_SESSION, userVO);

        Cookie cookie = new Cookie(CommonConst.USER_SESSION, String.valueOf(userVO.getUserId()));
        cookie.setPath("/");
        RequestUtil.getResponse().addCookie(cookie);

        return ResultData.success("success");
    }

    @DelayedResponse
    @PostMapping("/deleteUser")
    public ResultData<String> deleteUser(@RequestSingleParam("userId") Integer userId) throws SchedulerException {

        int i = userMapper.deleteById(userId);
        if (i > 0) {
            int update = taskTriggerMapper.update(Wrappers.<TaskTrigger>lambdaUpdate()
                    .set(TaskTrigger::getOpen, false)
                    .eq(TaskTrigger::getUserId, userId));
            log.info("[submitTasks]用户:[{}],已更新{}条记录", userId, update);

            apiService.deleteJobs(userId);
            return ResultData.success("success");
        }
        return ResultData.error("fail");
    }

    @DelayedResponse
    @PostMapping("/saveOrUpdateUser")
    public ResultData<String> saveOrUpdateUser(@RequestBody UserVO userVO) throws SchedulerException {

        boolean insert = userVO.getUserId() == null;

        boolean b = userMapper.insertOrUpdate(userVO);
        if (b) {
            if (insert) {
                TaskTrigger t1 = TaskTrigger.getInstance(1, userVO.getUserId(), Arrays.asList("08:00", "08:30"));
                TaskTrigger t2 = TaskTrigger.getInstance(2, userVO.getUserId(), Arrays.asList("18:00", "18:30"));
                apiService.saveTriggers(Arrays.asList(t1, t2), userVO.getUserId(), userVO.getUsername());
            }
            return ResultData.success("success");
        }
        return ResultData.error("fail");
    }

//    @Transactional(isolation = Isolation.READ_UNCOMMITTED)
    @PostMapping("/config/{userId}")
    public ResultData<RequestProperty> userConfig(@PathVariable("userId") Integer userId) {

        UserVO userVO = RequestUtil.getSessionUser();
        if (!Objects.equals(userId, userVO.getUserId())) {
            throw new IllegalArgumentException("用户信息不一致，从首页选择用户");
        }

        RequestProperty requestProperty = requestPropertyMapper.selectById(userId);

        if (requestProperty == null) {
            throw new IllegalArgumentException("数据为空");
        }

        return ResultData.success(requestProperty);
    }

    @PostMapping("/clock")
    public ResultData<String> clock() {

        UserVO userVO = RequestUtil.getSessionUser();

        RequestProperty requestProperty = requestPropertyMapper.selectById(userVO.getUserId());


        try (HttpResponse clock = ClockInUtil.clock(requestProperty)
//             HttpResponse clock = HttpUtil.createGet("https://www.baidu.com").execute();
        ) {
            return ResultData.success(clock.body());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    @PostMapping("/withdrawProperty")
    public ResultData<String> withdrawProperty(@RequestSingleParam("propertyStr") String propertyStr,
                                               @RequestSingleParam("type") String type) {

        UserVO userVO = RequestUtil.getSessionUser();

        RequestProperty property;
        if ("basicInfo".equals(type)) {
            property = RequestProperty.builder(propertyStr).build();
            property.setUserId(userVO.getUserId());
        } else {
            property = RequestProperty.clockParam(propertyStr).build();
            property.setUserId(userVO.getUserId());
        }

        property.setUpdateDate(DateUtil.date());
        boolean b = requestPropertyMapper.insertOrUpdate(property);
        if (!b) {
            return ResultData.error("操作失败");
        }

        return ResultData.success("success");
    }

    @PostMapping("/selfConfig")
    public ResultData<String> selfConfig(@RequestBody RequestProperty requestProperty) {

        UserVO userVO = RequestUtil.getSessionUser();
        requestProperty.setUserId(userVO.getUserId());

        requestProperty.setUpdateDate(DateUtil.date());
        boolean b = requestPropertyMapper.insertOrUpdate(requestProperty);
        if (!b) {
            return ResultData.error("操作失败");
        }

        return ResultData.success("success");
    }

    @PostMapping("/openJob")
    public ResultData<String> openJob(@RequestSingleParam("openJob") Boolean openJob) {
        UserVO userVO = RequestUtil.getSessionUser();

        userVO.setExecuteJob(openJob);

        int update = userMapper.update(Wrappers.<UserVO>lambdaUpdate()
                .set(UserVO::getExecuteJob, openJob)
                .eq(UserVO::getUserId, userVO.getUserId()));

        if (update > 0) {
            return ResultData.success("cu");
        }
        return ResultData.error("失败");
    }

    @PostMapping("/submitTasks")
    public ResultData<String> submitTasks(@RequestBody List<TaskTrigger> taskTriggers) throws SchedulerException {
        Assert.notNull(taskTriggers, "数据异常");

        final UserVO userVO = RequestUtil.getSessionUser();
        apiService.saveTriggers(taskTriggers, userVO.getUserId(), userVO.getUsername());

        return ResultData.success("success");
    }


    @PostMapping("/getJobConfig")
    public ResultData<JobConfig> getJobConfig() {

        UserVO userVO = RequestUtil.getSessionUser();

        List<TaskTrigger> taskTriggers = apiService.getTaskTrigger(userVO);

        JobConfig jobConfig = JobConfig.builder()
                .executeJob(userVO.getExecuteJob())
                .taskTriggers(taskTriggers)
                .executeForecasts(apiService.getExecuteForecast(userVO.getUserId(), 10))
                .build();

        return ResultData.success(jobConfig);
    }

    @DelayedResponse
    @PostMapping("/loadNextHistory")
    public ResultData<List<History>> loadNextHistory(@RequestSingleParam("fromDate") String fromDate) {

        UserVO userVO = RequestUtil.getSessionUser();
        if (userVO == null) {
            return ResultData.success(new ArrayList<>());
        }

        LambdaQueryWrapper<History> queryWrapper = Wrappers.<History>lambdaQuery()
                .eq(History::getUserId, userVO.getUserId());
        if (fromDate != null) {
            queryWrapper.lt(History::getAddDate, fromDate);
        }

        queryWrapper.orderByDesc(History::getAddDate)
                .last(" limit 10 ");

        List<History> histories = historyMapper.selectList(queryWrapper);

        return ResultData.success(histories);
    }

}
